package com.samp.solr.solrlstm;


import com.samp.util.FilesUtils;
import com.samp.util.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * solr读取测试数据，并生成模型训练数据.
 */
public class SolrValidate {

    private static Integer MATCH_SUCCESS_TOP5 = 0;
    private static Integer MATCH_ERROR_TOP5 = 0;

    private static Integer MATCH_SUCCESS_TOP1 = 0;
    private static Integer MATCH_ERROR_TOP1 = 0;

    private static Integer MATCH_SUCCESS_TOP10 = 0;
    private static Integer MATCH_ERROR_TOP10 = 0;

    public static void validateTestFile(String rawPath,String collectionName, String customPath, String stopwodsPath,
                      String synonymPath, String weightPath, Integer maxNum, String errorFile) throws Exception{
        Path filePath = Paths.get(rawPath);
        BufferedReader bufferReader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8);
        String line;
        long total_start = System.currentTimeMillis();
        try {
            //记录最多的错误意图并分析。如果为空，则记录所有错误意图。
            List<String> recordErrorIntentoin = new ArrayList();
            recordErrorIntentoin.add("action.name=查询#target.name=default#target.params1=default");
            String solrUrl = SolrlstmUtils.BASE_SOLR_URL+collectionName;
            SolrClient solrClient =new HttpSolrClient.Builder(solrUrl).build();
            int i = 0 ;
            long start = System.currentTimeMillis();
            //保存错误结果。
            List<String> errorMatchList = new ArrayList<>(10000);
            Set<String> errorMatchSet = new HashSet<>(10000);
            Map<String,Integer> errorIntentionDistribution = new HashMap<>();
            SolrlstmUtils.initialWeightMap(weightPath);
            TokenizeUtils.loCustomDict(customPath);
            TokenizeUtils.loadSynonymDict(synonymPath);
            TokenizeUtils.loadStopwordsDict(stopwodsPath);
            // 第一行是标题，忽略。
            bufferReader.readLine();
            while( (line = bufferReader.readLine()) != null ){
                String[] words = line.split("\t");
                if( words.length != 3 ){
                    System.out.println("error data:"+line);
                }
                String tokenText = TokenizeUtils.tokenize(words[1]);
                String testIntention = SolrlstmUtils.removeLastSlot(words[2]);
                if( StringUtils.isBlank(tokenText) ){
                    System.out.println("blank line :"+line);
                    continue;
                }
                List<WordIntention> topList = SolrlstmUtils.getTopNIntentions(solrClient, tokenText, SolrlstmUtils.TOP_N);
                boolean matchIntentionTop10 = false;
                boolean matchIntentionTop1 = false;
                boolean matchIntentionTop5 = false;
                String topIntention1 = "";
                for( int j = 0 ; j < topList.size() ; j++ ){
                    WordIntention wi = topList.get(j);
                    String topIntention = SolrlstmUtils.appendLastSlot(wi.getIntention(), tokenText);
                    if( j ==  0 ){
                        topIntention1 = topIntention;
                    }
                    if( SolrlstmUtils.isEqualIntention( testIntention,topIntention) ){
                        matchIntentionTop10 = true;
                        if( j == 0 ){
                            matchIntentionTop1 = true;
                        }
                        if( j < 5 ){
                            matchIntentionTop5 = true;
                        }
//                            System.out.println("match .........yes");
//                            System.out.println("yes........."+line);
//                            System.out.println("yes........."+topIntention);
                    }else {
//                            System.out.println("match .........no");
//                            System.out.println("no........."+line);
//                            System.out.println("no........."+topIntention);
                    }
                }
                if( matchIntentionTop1 ){
                    MATCH_SUCCESS_TOP1++;
                }else{
                    MATCH_ERROR_TOP1++;
                    if( topList.size() > 0 ) {
                        if (!errorMatchSet.contains(tokenText)) {
                            if( errorIntentionDistribution.get(testIntention) == null ){
                                errorIntentionDistribution.put(testIntention,0);
                            }
                            errorIntentionDistribution.put(testIntention,errorIntentionDistribution.get(testIntention)+1);
                            WordIntention wi = topList.get(0);
                            if( recordErrorIntentoin.contains(testIntention) || recordErrorIntentoin.size() == 0 ) {
                                errorMatchList.add(tokenText + "\t" + line + "\n\t=>" + wi.getWord() + "\t" + topIntention1);
                            }
                        } else {
                            errorMatchSet.add(tokenText);
                        }
                    }else {
                        errorMatchList.add(line + "\n\t=>" + "没有匹配结果");
                    }
                }
                if( matchIntentionTop10 ){
                    MATCH_SUCCESS_TOP10++;
                }else {
                    MATCH_ERROR_TOP10++;
                    //调试下top10错误代码。
//                        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//                        System.out.println("line = "+line);
//                        for( int j = 0 ; j < topList.size() ; j++ ) {
//                            String topIntention = topList.get(j);
//                            System.out.println("===:"+topIntention);
//                        }
//                        System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
                }
                if( matchIntentionTop5 ){
                    MATCH_SUCCESS_TOP5++;
                }else {
                    MATCH_ERROR_TOP5++;
                }
                if( MATCH_SUCCESS_TOP5 + MATCH_ERROR_TOP5 > maxNum ){
                    break;
                }
                i++;
                if( i % 5000 == 0  ){
                    System.out.println("cost:"+(System.currentTimeMillis()-start));
                    start = System.currentTimeMillis();
                    System.out.println("current result.MATCH_SUCCESS_TOP1="+ MATCH_SUCCESS_TOP1 +", MATCH_ERROR_TOP1="+ MATCH_ERROR_TOP1);
                    System.out.println("current result.MATCH_SUCCESS_TOP5="+ MATCH_SUCCESS_TOP5 +", MATCH_ERROR_TOP5="+ MATCH_ERROR_TOP5);
                    System.out.println("current result.MATCH_SUCCESS_TOP10="+ MATCH_SUCCESS_TOP10 +", MATCH_ERROR_TOP10="+ MATCH_ERROR_TOP10);
                    System.out.println("当前TOP1正确率="+(MATCH_SUCCESS_TOP1.floatValue())/(MATCH_SUCCESS_TOP1 + MATCH_ERROR_TOP1));
                    System.out.println("当前TOP5正确率="+(MATCH_SUCCESS_TOP5.floatValue())/(MATCH_SUCCESS_TOP5 + MATCH_ERROR_TOP5));
                    System.out.println("当前TOP10正确率="+(MATCH_SUCCESS_TOP10.floatValue())/(MATCH_SUCCESS_TOP10 + MATCH_ERROR_TOP10));
                }
            }
            //保存错误记录
            if( StringUtils.isNotBlank(errorFile) ) {
                FilesUtils.saveListToFile(errorMatchList, errorFile);
            }
            //打印错误意图分布情况
            System.out.println("top1错误意图大小，"+errorIntentionDistribution.size()+",分布如下：");
            Map sortMap = MapUtils.sortedByValue(errorIntentionDistribution);
            Iterator iterator = sortMap.entrySet().iterator();
            while ( iterator.hasNext() ){
                Map.Entry entry = (Map.Entry)iterator.next();
                String wordNum = entry.getKey()+":"+entry.getValue();
                System.out.println(wordNum);
            }

        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            bufferReader.close();
        }
        System.out.println("last result.MATCH_SUCCESS_TOP1="+ MATCH_SUCCESS_TOP1 +", MATCH_ERROR_TOP1="+ MATCH_ERROR_TOP1);
        System.out.println("last result.MATCH_SUCCESS_TOP5="+ MATCH_SUCCESS_TOP5 +", MATCH_ERROR_TOP5="+ MATCH_ERROR_TOP5);
        System.out.println("last result.MATCH_SUCCESS_TOP10="+ MATCH_SUCCESS_TOP10 +", MATCH_ERROR_TOP10="+ MATCH_ERROR_TOP10);
        System.out.println("最终TOP1正确率="+(MATCH_SUCCESS_TOP1.floatValue())/(MATCH_SUCCESS_TOP1 + MATCH_ERROR_TOP1));
        System.out.println("最终TOP5正确率="+(MATCH_SUCCESS_TOP5.floatValue())/(MATCH_SUCCESS_TOP5 + MATCH_ERROR_TOP5));
        System.out.println("最终TOP10正确率="+(MATCH_SUCCESS_TOP10.floatValue())/(MATCH_SUCCESS_TOP10 + MATCH_ERROR_TOP10));
        System.out.println("总共耗时："+(System.currentTimeMillis()-total_start)/(1000.0*60.0));
    }

    public static void main(String[] args) {
        String callMethod = "validateTestFile";
        String collectionDirName = "lifeareanavi";
        String collectionFullPath = SolrlstmUtils.BASE_PATH+collectionDirName+"\\";
        String testFilePath = collectionFullPath+"raw_test_data.txt";
        String customPath = collectionFullPath+"tokenize_custom_xx.txt";
        String synonymPath = collectionFullPath+"tokenize_synonym_xx.txt";
        String weightPath = collectionFullPath+"tokenize_weight_xx.txt";
        String stopwordsPath = collectionFullPath+"stopwords.txt";
        String collectionName = "GCC-OMCP_NLPLifeAreaExtensionNavi";
        Integer maxNum = 100000;
        try{
            if ("validateTestFile".equals(callMethod)) {
                String errorFile = collectionFullPath+"top1_no_match_01.txt";
                validateTestFile(testFilePath,collectionName,customPath,stopwordsPath,synonymPath,weightPath,maxNum,errorFile);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
